/** Keriosity, ESIR 2
 * 	Gyroscope (Modele): classe detectant les mouvements de l'utilisateur 
 *  et envoyant les ordres correspondant au IManual
 *	@author: GOUYET Brett
 *	@date: 15/05/2012
 */

package keriosity.gyroscope;

import keriosity.core.IManual;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;


/** Classe permettant de gerer l'envoi d'ordres en fonction des mouvements **/
public class Gyroscope implements IGyroscope{
		
	protected IManual _manualObservable = null; //observable a qui on enverra les ordres
	protected Context _context = null;
	protected Sensor _sensor = null;
	protected SensorEventListener _sensorListener = null;
	protected SensorManager _sensorManager = null;
	protected boolean _isActived = false; //vrai si active, faux sinon

	
	/** CONSTRUCTEUR **/
	public Gyroscope(IManual manualObservable, Context context){
			
		//on defini notre observable a qui on enverra les ordres
		_manualObservable = manualObservable;
		_context = context;
		
		//on recupere le capteur Accelerometre qui va nous permettre de connaitre l'inclinaison
		_sensorManager = (SensorManager) _context.getSystemService(Context.SENSOR_SERVICE);
		_sensor = _sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
	}
	
	
	/** Methode demarrant ou arretant le mode gyro **/
    public void activateSensor(boolean activate) {
    	
    	if(activate){    			 
			_sensorListener = new SensorMoving(); //le listener est a l'ecoute de l'inclinaison de la tablette
			_sensorManager.registerListener(_sensorListener, _sensor, SensorManager.SENSOR_DELAY_GAME);    	
			_isActived = true;
    	}	
    	else{
    		_sensorManager.unregisterListener(_sensorListener, _sensor);
    		_sensorListener = null;
    		_isActived = false;
    	}
    }
    
    
    /** Methode donnant le statut du gyroscope: active ou non **/
    public boolean isActived(){
    	return _isActived;
    }
 
	
    /** Classe SensorMoving permettant de detecter les mouvements de 
     * l'utilisateur et d'envoyer les ordres en consequence
     */
    class SensorMoving implements SensorEventListener{
    	
    	int ordre = 0; //permet de ne pas envoyer plusiers fois le meme ordre
		
		public void onSensorChanged(SensorEvent pEvent) {
		    
			/** On a deux axes X et Y, X represente l'axe horizontal de la tablette, plus il est negatif, plus on penche 
			 * a droite, plus il est positif plus on penche a gauche. L'axe Y represente l'axe vertical de la tablette,
			 * plus il est positif et plus on penche en arriere, plus il est negatif et plus on penche en avant **/
			
			//on recupere la valeur des deux axes
			float x = pEvent.values[0];
		    float y = pEvent.values[1];
		    
       
		    /** On a defini les valeurs x et y de sensibilite de facon arbitraire au cours de test **/
		    if(x > -1 && x < 1 && y > -1 && y < 2 && ordre != 5){ //on s'arrete
				ordre = 5;
				_manualObservable.gyroStop();
			}		    
		    
		    if(x > -1 && x < 1  && y > -4 && y < -1 && ordre != 1){ //on avance
		    	ordre = 1;
		    	_manualObservable.gyroMove();
		    }
		    
		    if(x > -4 && x < -2 &&  y > -1 && y < 2 && ordre != 3){ //on va a droite
				ordre = 3;
				_manualObservable.gyroRight();				
			}
		
			if(x > -1 && x < 1 && y > 5 && y < 7 && ordre != 2){ //on recule
				ordre = 2;
				_manualObservable.gyroBack();
			}
			
			if(x > 3 && x < 5 &&  y > -1 && y < 2 && ordre != 4){ //on va a gauche
				ordre = 4;
				_manualObservable.gyroLeft();					
			}
		}
		        
		 
        //methode non utilisee
        public void onAccuracyChanged(Sensor pSensor, int pAccuracy) {}
	}//SensorMoving
    
}
